/******************************************************************************
 *                                                                          
 * Copyright (c) 2008 Nuvoton Technology. All rights reserved.             
 *                                                                
 * 
 * FILENAME
 *     NUC900_IIS.c
 *
 * VERSION
 *     0.1 
 *
 * DESCRIPTION
 *
 *
 *
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *
 *
 *     
 * HISTORY
 *     2007.09.27		Created by Shih-Jen Lu
 *
 *
 * REMARK
 *     None
 *
 *
 **************************************************************************/
#ifdef ECOS
#include "stdio.h"
#include "stdlib.h"
#include "kapi.h"
#include "diag.h"
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wblib.h"
#endif

#include "wbio.h"
#include "NUC900_Audio_Regs.h"
#include "NUC900_Audio.h"

#include "IIS.h"


#ifdef HAVE_I2S

static BOOL bInitWM8978 = 0; 
static BOOL  _bI2S_PW_UP =FALSE;
extern BOOL g_fInUse[];
//static UINT32 _uIISCR = 0;
UINT8 g_I2SAudioFormat = I2S_FORMAT;//default data format
static BOOL	volatile _bPlayDmaToggle, _bRecDmaToggle;

static VOID I2S_SetDataFormat(VOID);
static BOOL I2S_SetSampleRate(INT);
static INT  i2sStartPlay(PWAVEFORMATEX pFormat);
static INT  i2sStartRecord(PWAVEFORMATEX pFormat);
static VOID i2sStopPlay(VOID);
static VOID i2sStopRecord(VOID);


static void Delay(int nCnt)
{
	 int volatile loop;
	for (loop=0; loop<nCnt*10; loop++);
}

#ifdef ECOS
cyg_uint32  iis_isr(cyg_vector_t vector, cyg_addrword_t data)
#else
static void  iis_isr()
#endif
{
	if (inpw(REG_ACTL_CON) & T_DMA_IRQ)
	{
	    writew(REG_ACTL_CON, readw(REG_ACTL_CON) | T_DMA_IRQ);//Clear TX INT
	    if ((readw(REG_ACTL_PSR) & P_DMA_MIDDLE_IRQ) && (readw(REG_ACTL_PSR)&P_DMA_END_IRQ))
    	{
    		_debug_msg("psr=0x%x\n",inpw(REG_ACTL_PSR));
    		writew(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ | P_DMA_END_IRQ);
    		_debug_msg("both mid and end isr  psr=0x%x\n",inpw(REG_ACTL_PSR));
#ifdef ECOS
			cyg_interrupt_acknowledge(IRQ_ACTL);
			return CYG_ISR_HANDLED;
#else
            return;
#endif
    	}
		
		if (readw(REG_ACTL_PSR) & DMA_COUNTER_IRQ)
		{
			writew(REG_ACTL_PSR, DMA_COUNTER_IRQ);
			_debug_msg("\ndebug:DMA_COUNTER_IRQ occur");
		}
		
		if (readw(REG_ACTL_PSR) & DMA_DATA_ZERO_IRQ)
		{
			writew(REG_ACTL_PSR, DMA_DATA_ZERO_IRQ);
			_debug_msg("\ndebug:DMA_DATA_ZERO_IRQ occur");
		}
	
		if (_bPlayDmaToggle == 0)
		{
		    if (readw(REG_ACTL_PSR) & P_DMA_MIDDLE_IRQ)
		    {
		    	writew(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ);
		    	g_fnWAVOutCallBack((UINT8 *)_uAuPlayBuffUncachedAddr, 
		    											_uAuPlayBuffSize/2);
		    }
		    else if (readw(REG_ACTL_PSR) & P_DMA_END_IRQ)
		    {
		    	writew(REG_ACTL_PSR, P_DMA_END_IRQ);
		    	g_fnWAVOutCallBack((UINT8 *)(_uAuPlayBuffUncachedAddr + _uAuPlayBuffSize/2), 
		    								_uAuPlayBuffSize/2);
		    }
		}
	}
	
	if (inpw(REG_ACTL_CON) & R_DMA_IRQ)
	{
		writew(REG_ACTL_CON, readw(REG_ACTL_CON) | R_DMA_IRQ);//Clear RX INT
        if ((readw(REG_ACTL_RSR) & R_DMA_MIDDLE_IRQ) && (readw(REG_ACTL_RSR)&R_DMA_END_IRQ))
    	{
    		_debug_msg("psr=0x%x\n",inpw(REG_ACTL_RSR));
    		writew(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ | R_DMA_END_IRQ);
    		_debug_msg("both mid and end isr  psr=0x%x\n",inpw(REG_ACTL_RSR));
#ifdef ECOS
			cyg_interrupt_acknowledge(IRQ_ACTL);
			return CYG_ISR_HANDLED;
#else
            return;
#endif
    	}
    	if (_bRecDmaToggle == 0)
    	{               
		    if (readw(REG_ACTL_RSR) & R_DMA_MIDDLE_IRQ)
		    {
		    	writew(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ);
		    	g_fnWAVInCallBack((UINT8 *)_uAuRecBuffUncachedAddr, _uAuRecBuffSize/2);
		    }
		    else if (readw(REG_ACTL_RSR) & R_DMA_END_IRQ)
		    {
		    	writew(REG_ACTL_RSR, R_DMA_END_IRQ);
		    	g_fnWAVInCallBack((UINT8 *)(_uAuRecBuffUncachedAddr + _uAuRecBuffSize/2), 
		    								_uAuRecBuffSize/2);
		    }
		}
	}
#ifdef ECOS
			cyg_interrupt_acknowledge(IRQ_ACTL);
			return CYG_ISR_HANDLED;
#endif
}	
static BOOL InitI2S(void)
{
	outpw(REG_MFSEL,inpw(REG_MFSEL) | (3<<22));
	if (!_bI2S_PW_UP)
	{
	    /* reset audio interface */
	    writew(REG_ACTL_RESET,readw(REG_ACTL_RESET) | ACTL_RESET_BIT);
	    Delay(100);
	    writew(REG_ACTL_RESET,readw(REG_ACTL_RESET) & ~ACTL_RESET_BIT);
	    Delay(100);
	    
	    /* reset IIS interface */
	    writew(REG_ACTL_RESET,readw(REG_ACTL_RESET) | I2S_RESET);
	    Delay(100);
	    writew(REG_ACTL_RESET,readw(REG_ACTL_RESET) & ~I2S_RESET);
	    Delay(100);
	    _bI2S_PW_UP = TRUE;
	}
	/* enable audio controller and IIS interface */
	writew(REG_ACTL_CON, readw (REG_ACTL_CON) &~I2S_AC_PIN_SEL | I2S_EN | T_DMA_IRQ | R_DMA_IRQ);

	return TRUE;
}
	
static BOOL I2SCodecPowerOn(WAPI_INOUT apidir ,PWAVEFORMATEX pFormat)
{
    BOOL bRetVal=TRUE;
#ifdef HAVE_I2S_UDA1345
    bRetVal = uda1345tsPowerOn(apidir ,pFormat);
    return bRetVal;
#endif

    return bRetVal;

    
}
/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*      I2S_SetPlayVolume                                                   */
/*                                                                       */
/* DESCRIPTION                                                           */
/*      Set I2S left and right channel play volume.                     */
/*                                                                       */
/* INPUTS                                                                */
/*      uVolume    play volume of left & right channel                   */
/*                 16 bits of right (0xRRRRLLLL)                         */
/*                  0:  mute                                             */
/*             0xffff: maxmum volume                                     */
/*                                                                       */
/*                                                                       */
/* OUTPUTS                                                               */
/*      None                                                             */
/*                                                                       */
/* RETURN                                                                */
/*      0           Success                                              */
/*		Otherwise	error												 */
/*                                                                       */
/*************************************************************************/
BOOL I2S_SetPlayVolume(UINT32 uVolume)
{
    BOOL bRetVal=TRUE;
#ifdef HAVE_I2S_UDA1345
    bRetVal = uda1345tsSetPlayVolume(uVolume);
    return bRetVal;
#endif

#ifdef HAVE_I2S_WM8978
	UINT8 ucLeftVol, ucRightVol;
	ucLeftVol = (UINT8)(uVolume & 0x000000FF);
	ucRightVol =(UINT8)((uVolume & 0x00FF0000) >> 16);  //six bits of volume
	
	if(ucRightVol >= 32)
		ucRightVol = 32;
	if(ucLeftVol >= 32)
		ucLeftVol = 32;
	_debug_msg("play volume=R:%d, L:%d\n", ucRightVol, ucLeftVol);
	WM8978_Set_DAC_Volume(ucLeftVol, ucRightVol);    
#endif

    return bRetVal;
}

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*      I2S_SetRecVolume                                                   */
/*                                                                       */
/* DESCRIPTION                                                           */
/*      Set I2S left and right channel play volume.                     */
/*                                                                       */
/* INPUTS                                                                */
/*      uVolume    play volume of left & right channel                   */
/*                 16 bits of right (0xRRRRLLLL)                         */
/*                  0:  mute                                             */
/*             0xffff: maxmum volume                                     */
/*                                                                       */
/*                                                                       */
/* OUTPUTS                                                               */
/*      None                                                             */
/*                                                                       */
/* RETURN                                                                */
/*      0           Success                                              */
/*		Otherwise	error												 */
/*                                                                       */
/*************************************************************************/
static BOOL I2S_SetRecVolume(UINT32 uVolume)
{
    BOOL bRetVal=TRUE;

#ifdef HAVE_I2S_WM8978
	UINT8 ucLeftVol, ucRightVol;
	ucLeftVol = (UINT8)(uVolume & 0x000000FF);
	ucRightVol =(UINT8)((uVolume & 0x00FF0000) >> 16);  //six bits of volume
	
	if(ucRightVol >= 32)
		ucRightVol = 32;
	if(ucLeftVol >= 32)
		ucLeftVol = 32;
	
	_debug_msg("rec volume=R:%d, L:%d\n", ucRightVol, ucLeftVol);	
	WM8978_Set_ADC_Volume(ucLeftVol, ucRightVol);    
#endif

    return bRetVal;
}
static BOOL
AudioOutMute(
   BOOL mute
   )
{
    BOOL bRetVal=TRUE;
#ifdef HAVE_I2S_UDA1345
    bRetVal = uda1345SetOutMute(mute);
    return bRetVal;
#endif

    return bRetVal;    
}
static BOOL
AudioInMute(
   BOOL mute
   )
{
    BOOL bRetVal=TRUE;
#ifdef HAVE_I2S_UDA1345
    bRetVal = FALSE;
    return bRetVal;
#endif

    return bRetVal;
}
INT Initialize_I2S(WAPI_INOUT apidir ,PWAVEFORMATEX pFormat)
{

    if (InitI2S()==FALSE)
        return ERR_AU_INITDEV_FAIL;
        
    if (I2SCodecPowerOn(apidir ,pFormat)==FALSE)//TODO: if error occur, must power off
        return ERR_AU_INITDEV_FAIL;
    
    if (apidir==WAPI_OUT)
    {
        if (pFormat->fnWAVCallBack==NULL)
            return ERR_AU_INITDEV_FAIL;
            
        g_fnWAVOutCallBack = pFormat->fnWAVCallBack;
    }
    else
    {
        if (pFormat->fnWAVCallBack==NULL)
            return ERR_AU_INITDEV_FAIL;
        g_fnWAVInCallBack = pFormat->fnWAVCallBack;

    }
    
    // Initialize audio[I2S] ISR
#ifdef ECOS
    //sysSetInterruptType(IRQ_ACTL, HIGH_LEVEL_SENSITIVE);
	//cyg_interrupt_configure(AU_REC_INT_NUM, 1 , 0);
    cyg_interrupt_create(IRQ_ACTL, 1, 0, iis_isr, NULL, 
    					&pFormat->int_handle_audio, &pFormat->int_holder_audio);
    cyg_interrupt_attach(pFormat->int_handle_audio);
    cyg_interrupt_unmask(IRQ_ACTL);
#else
    sysSetInterruptType(IRQ_ACTL, HIGH_LEVEL_SENSITIVE);
    sysInstallISR(IRQ_LEVEL_1, IRQ_ACTL, (PVOID)iis_isr);
    sysEnableInterrupt(IRQ_ACTL);
#endif

#ifdef HAVE_I2S_WM8978
    if(!bInitWM8978)
    {
    	WM8978_Init();
    	bInitWM8978 = 1;
    }
#endif

    return 0;
    
}

BOOL WaveProc_I2S(
    WAPI_INOUT apidir,
    UINT32      nCode,
    UINT32      nParam1,
    UINT32      nParam2
    )
{
    switch(nCode)
    {
        case WPDM_START:
            if (apidir==WAPI_OUT)
            {
                i2sStartPlay((PWAVEFORMATEX) nParam1);
            }else
            {
                i2sStartRecord((PWAVEFORMATEX) nParam1);
            }
            break;
        case WPDM_STOP:
            if (apidir==WAPI_OUT)
            {
                i2sStopPlay();
            }else
            {
                i2sStopRecord();
            }
            break;
        case WPDM_SETPLAYVOLUME:
            v_nVolume = nParam1;
            I2S_SetPlayVolume(*((PUINT32) nParam1));
            break;
         case WPDM_SETRECVOLUME:
            v_nVolume = nParam1;
            I2S_SetRecVolume(*((PUINT32) nParam1));
            break;
        case WPDM_GETVOLUME:
            *((PUINT32) nParam1) = v_nVolume;
            break;
        default:
            return FALSE;
    }
    return TRUE;
}

/*----- set data format -----*/
static void I2S_SetDataFormat()
{
    UINT32 ndata;
    
	switch(g_I2SAudioFormat){
		case I2S_FORMAT: ndata = I2S;
				break;
		case MSB_FORMAT: ndata = MSB_Justified;
				break;
		default:break;
	}
	writew(REG_ACTL_IISCON,inpw(REG_ACTL_IISCON)&~(1<<3) | ndata);
}

/*----- set sample Frequency -----*/
static BOOL I2S_SetSampleRate(int choose_sf)
{

#if defined(HAVE_I2S_WM8978) || defined(HAVE_I2S_UDA1345)
    UINT32 ndata=0;
	switch (choose_sf)
	{
		case AU_SAMPLE_RATE_8000:							//8KHz
			ndata = FS32 | SCALE_4 | BCLK_MCLKDIV12;
			//_uIISCR = _uIISCR | FS32 | SCALE_5 | BCLK_MCLKDIV8;//for test
			break;
		case AU_SAMPLE_RATE_11025:					//11.025KHz
			ndata = FS32 | SCALE_4 | BCLK_MCLKDIV12;
			break;
		case AU_SAMPLE_RATE_12000:
			ndata = FS32 | SCALE_4 | BCLK_MCLKDIV8;
			break;
		case AU_SAMPLE_RATE_16000:						//16KHz
			ndata = FS32 | SCALE_2 | BCLK_MCLKDIV12;
			break;
		case AU_SAMPLE_RATE_22050:					//22.05KHz
			ndata = FS32 | SCALE_3 | BCLK_MCLKDIV8;
			break;
		case AU_SAMPLE_RATE_24000:						//24KHz
			ndata = FS32 | SCALE_2 | BCLK_MCLKDIV8;
			break;
		case AU_SAMPLE_RATE_32000:						//32KHz
			ndata = SCALE_1 | FS32  | BCLK_MCLKDIV12;
			break;
		case AU_SAMPLE_RATE_44100:					//44.1KHz
			ndata = SCALE_1 | FS32  | BCLK_MCLKDIV12;
			//_uIISCR = _uIISCR | SCALE_1 | FS32  | BCLK_MCLKDIV8;//for test
			break;
		case AU_SAMPLE_RATE_48000:						//48KHz
			ndata =  FS32 | SCALE_1 | BCLK_MCLKDIV8;
			break;
		default:
		return FALSE;
		break;
	}
	writew(REG_ACTL_IISCON,inpw(REG_ACTL_IISCON)&~(0xf00f0) | ndata);
	//return TRUE;
#endif

#ifdef HAVE_I2S_PCM3003
    UINT32 ndata=0;
	switch (choose_sf)
	{
		case AU_SAMPLE_RATE_8000:							//8KHz
			ndata = FS32 | SCALE_4 | BCLK_MCLKDIV12;
			//_uIISCR = _uIISCR | FS32 | SCALE_5 | BCLK_MCLKDIV8;//for test
			break;
		case AU_SAMPLE_RATE_11025:					//11.025KHz
			ndata = FS32 | SCALE_4 | BCLK_MCLKDIV12;
			break;
		case AU_SAMPLE_RATE_12000:
			ndata = FS32 | SCALE_4 | BCLK_MCLKDIV8;
			break;
		case AU_SAMPLE_RATE_16000:						//16KHz
			ndata = FS32 | SCALE_2 | BCLK_MCLKDIV12;
			break;
		case AU_SAMPLE_RATE_22050:					//22.05KHz
			ndata = FS32 | SCALE_3 | BCLK_MCLKDIV8;
			break;
		case AU_SAMPLE_RATE_24000:						//24KHz
			ndata = FS32 | SCALE_2 | BCLK_MCLKDIV8;
			break;
		case AU_SAMPLE_RATE_32000:						//32KHz
			ndata = SCALE_1 | FS32  | BCLK_MCLKDIV12;
			break;
		case AU_SAMPLE_RATE_44100:					//44.1KHz
			ndata = SCALE_1 | FS32  | BCLK_MCLKDIV12;
			//_uIISCR = _uIISCR | SCALE_1 | FS32  | BCLK_MCLKDIV8;//for test
			break;
		case AU_SAMPLE_RATE_48000:						//48KHz
			ndata =  FS32 | SCALE_1 | BCLK_MCLKDIV8;
			break;
		default:
		return FALSE;
		break;
	}
	writew(REG_ACTL_IISCON,inpw(REG_ACTL_IISCON)&~(0xf00f0) | ndata);
	//return TRUE;
#endif

#ifdef HAVE_I2S_WM8978
{
	extern int uSamplingRate;
	uSamplingRate = choose_sf;
}
#endif
	outpw(REG_CLKEN,inpw(REG_CLKEN)&~(2));//ACLK off
	if ((choose_sf%AU_SAMPLE_RATE_8000==0) || (choose_sf==AU_SAMPLE_RATE_12000))
	{
		outpw(REG_CLKSEL,inpw(REG_CLKSEL)&~(3<<4) | (1<<4));//ACLK from PLL1
		outpw(REG_PLLCON1,0x92E7);//PLL1=86Mhz
		outpw(REG_CLKDIV,inpw(REG_CLKDIV) & ~(0xF<<8) | (9<<8));
	}
	else
	{
		outpw(REG_CLKSEL,inpw(REG_CLKSEL)&~(3<<4) | (1<<4));//ACLK from PLL1
		outpw(REG_PLLCON1,0x4E25);////PLL1=67.5Mhz
		outpw(REG_CLKDIV,inpw(REG_CLKDIV) & ~(0xF<<8) | (9<<8));
	}
	outpw(REG_CLKEN,inpw(REG_CLKEN)| 2);//ACLK on
	//while(nwait--);

}

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*      i2sStartPlay                                                   */
/*                                                                       */
/* DESCRIPTION                                                           */
/*      Start IIS playback.                                             */
/*                                                                       */
/* INPUTS                                                                */
/*      fnCallBack     client program provided callback function. The audio */
/*                  driver will call back to get next block of PCM data  */
/*      nSamplingRate  the playback sampling rate. Supported sampling    */
/*                  rate are 48000, 44100, 32000, 24000, 22050, 16000,   */
/*                  11025, and 8000 Hz                                   */
/*                                                                       */
/* OUTPUTS                                                               */
/*      None                                                             */
/*                                                                       */
/* RETURN                                                                */
/*      0           Success                                              */
/*		Otherwise	error												 */
/*                                                                       */
/*************************************************************************/
static INT  i2sStartPlay(PWAVEFORMATEX pFormat)
{

    AudioOutMute(FALSE);
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) & ~ PLAY_LEFT_CHNNEL & ~ PLAY_RIGHT_CHNNEL);
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) | PLAY_RIGHT_CHNNEL);
	if (pFormat->sChannels == AU_CH_STEREO)
		writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) | PLAY_LEFT_CHNNEL);
	
	//writew(REG_ACTL_CON, readw (REG_ACTL_CON) | IRQ_DMA_COUNTER_EN | IRQ_DMA_DATA_ZERO_EN);

	/* set play sampling rate and data format */
	if (I2S_SetSampleRate(pFormat->nSamplesPerSec)==FALSE)
	{
	    _debug_msg("Error - sample rate %d not support!!\n",pFormat->nSamplesPerSec);
		return FALSE;
	}
	
	I2S_SetDataFormat();
	
	
	/* set DMA play destination base address */
	writew(REG_ACTL_PDSTB, _uAuPlayBuffPHYAddr);
	
	/* set DMA play buffer length */
	writew(REG_ACTL_PDST_LENGTH, _uAuPlayBuffSize);

	/* call back to fill DMA play buffer */
	g_fnWAVOutCallBack((UINT8 *)_uAuPlayBuffUncachedAddr, _uAuPlayBuffSize);

#ifdef HAVE_I2S_WM8978	
	WM8978_DAC_Setup();
#endif
	
	/* start playing */
	_debug_msg("IIS start playing...\n");
	writew(REG_ACTL_PSR, 0x3);
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) | I2S_PLAY );
	//writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) | DMA_COUNTER_EN);

	return 0;
}


/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*      i2sStopPlay                                                    */
/*                                                                       */
/* DESCRIPTION                                                           */
/*      Stop IIS playback immdediately.                                 */
/*                                                                       */
/* INPUTS                                                                */
/*      None    	                                                     */
/*                                                                       */
/* OUTPUTS                                                               */
/*      None                                                             */
/*                                                                       */
/* RETURN                                                                */
/*      0           Success                                              */
/*		Otherwise	error												 */
/*                                                                       */
/*************************************************************************/
static VOID  i2sStopPlay()
{
	
	_debug_msg("IIS stop playing\n");

	/* stop playing */
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) & ~I2S_PLAY );
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) & ~(PLAY_RIGHT_CHNNEL | PLAY_LEFT_CHNNEL));
	AudioOutMute(TRUE);
	
	return;
}


/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*      i2sStartRecord                                                 */
/*                                                                       */
/* DESCRIPTION                                                           */
/*      Start IIS record.                                               */
/*                                                                       */
/* INPUTS                                                                */
/*      fnCallBack     client program provided callback function. The audio */
/*                  driver will call back to deliver the newly recorded  */
/*                  block of PCM data                                    */
/*      nSamplingRate  the record sampling rate. Supported sampling      */
/*                  rate are 48000, 44100, 32000, 24000, 22050, 16000,   */
/*                  11025, and 8000 Hz                                   */
/*                                                                       */
/* OUTPUTS                                                               */
/*      None                                                             */
/*                                                                       */
/* RETURN                                                                */
/*      0           Success                                              */
/*		Otherwise	error												 */
/*                                                                       */
/*************************************************************************/
static INT  i2sStartRecord(PWAVEFORMATEX pFormat)
{
	AudioInMute(FALSE);	
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) & ~RECORD_LEFT_CHNNEL & ~RECORD_RIGHT_CHNNEL);
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) | RECORD_LEFT_CHNNEL);
	if (pFormat->sChannels != 1)
		writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) | RECORD_RIGHT_CHNNEL);
	
	/* Install IIS record interrupt */
#ifdef ECOS
	cyg_interrupt_unmask(IRQ_ACTL);
	//cyg_interrupt_enable();
#else	
	//sysSetLocalInterrupt(ENABLE_IRQ);	/* enable CPSR I bit */
	sysEnableInterrupt(IRQ_ACTL);
#endif

	/* set record sampling rate and data format */

	I2S_SetSampleRate(pFormat->nSamplesPerSec);
	I2S_SetDataFormat();

	/* set DMA record destination base address */
	writew(REG_ACTL_RDSTB, _uAuRecBuffPHYAddr);
	
	/* set DMA record buffer length */
	writew(REG_ACTL_RDST_LENGTH, _uAuRecBuffSize);

#ifdef HAVE_I2S_WM8978	
	WM8978_ADC_Setup();	
#endif
		
	/* start recording */
	_debug_msg("IIS start recording...\n");
	writew(REG_ACTL_RSR, 0x3);
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) | I2S_RECORD);

	return 0;
}


/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*      i2sStopRecord                                                  */
/*                                                                       */
/* DESCRIPTION                                                           */
/*      Stop IIS record immediately.                                    */
/*                                                                       */
/* INPUTS                                                                */
/*      None    	                                                     */
/*                                                                       */
/* OUTPUTS                                                               */
/*      None                                                             */
/*                                                                       */
/* RETURN                                                                */
/*      0           Success                                              */
/*		Otherwise	error												 */
/*                                                                       */
/*************************************************************************/
static VOID  i2sStopRecord(VOID)
{	
	_debug_msg("I2S stop recording\n");

	/* stop recording */
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) & ~I2S_RECORD);
	writew(REG_ACTL_RESET, readw(REG_ACTL_RESET) & ~(RECORD_RIGHT_CHNNEL | RECORD_LEFT_CHNNEL));
	AudioInMute(TRUE);

	return;
}
#endif	/* HAVE_IIS */